#pragma once

#pragma once

static const char index_body[] =
    "<!doctype html><html><head><meta charset='utf-8'><title>WiFi 配网</title>"
    "<meta name='viewport' content='width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no'/>"
    "<style>"
    ":root{--bg:#f5f7fb;--card:#fff;--txt:#1f2328;--muted:#6b7380;--line:#e6e8eb;--line2:#f0f1f3;--pri:#0b6bff;--pri-weak:rgba(11,107,255,.12);--shadow:0 6px 24px rgba(31,35,40,.06);--ok:#127c3e;--warn:#9a6c00;--err:#c21d2e}"
    "@media(prefers-color-scheme:dark){:root{--bg:#0c1116;--card:#0f141a;--txt:#e6edf3;--muted:#9aa4b2;--line:#202733;--line2:#1b2230;--pri:#4c8dff;--pri-weak:rgba(76,141,255,.16);--shadow:0 8px 28px rgba(0,0,0,.45)}}"
    "html,body{height:100%}"
    "body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;margin:0;background:var(--bg);color:var(--txt);-webkit-tap-highlight-color:transparent}"
    ".wrap{min-height:100%;display:flex;align-items:center;justify-content:center;padding:clamp(12px,3vw,24px)}"
    ".card{width:min(760px,92vw);background:var(--card);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow);overflow:hidden}"
    ".hd{padding:16px 20px;border-bottom:1px solid var(--line2);background:linear-gradient(180deg,#fafbfc00,rgba(255,255,255,.06))}"
    ".title{margin:0;font-size:clamp(17px,2.2vw,20px);font-weight:800;color:var(--txt);display:flex;align-items:center;gap:10px;letter-spacing:.2px}"
    ".title:before{content:\"\";display:inline-block;width:10px;height:10px;border-radius:50%;background:var(--pri);box-shadow:0 0 0 3px var(--pri-weak)}"
    ".bd{padding:clamp(14px,3vw,22px)}"
    ".row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}"
    "label{display:block;margin:.6rem 0 .35rem;color:var(--muted);font-size:13px}"
    "input,button,select{font-size:16px}"
    "input{width:100%;padding:.78rem .9rem;border:1px solid var(--line);background:transparent;color:var(--txt);border-radius:10px;outline:none;transition:border .15s ease,box-shadow .15s ease}"
    "input::placeholder{color:#9aa4b2}"
    "input:focus{border-color:var(--pri);box-shadow:0 0 0 4px var(--pri-weak)}"
    ".btn{display:inline-flex;align-items:center;gap:.5em;background:var(--pri);color:#fff;border:none;border-radius:999px;padding:.78rem 1.15rem;cursor:pointer;transition:transform .08s ease,box-shadow .15s ease;letter-spacing:.2px}"
    ".btn:hover{box-shadow:0 10px 24px rgba(11,107,255,.28)}"
    ".btn:active{transform:translateY(1px)}"
    ".btn.sec{background:#636c78}"
    ".muted{color:var(--muted)}"
    ".list{margin-top:12px;max-height:min(320px,42vh);overflow:auto;border:1px solid var(--line);border-radius:10px;background:transparent}"
    ".item{display:flex;justify-content:space-between;align-items:center;padding:12px 14px;border-bottom:1px solid var(--line2);cursor:pointer}"
    ".item:hover{background:rgba(127,127,127,.06)}"
    ".item:last-child{border-bottom:none}"
    ".ssid{font-weight:700;letter-spacing:.15px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:70%}"
    ".rssi{font-size:12px;color:var(--muted)}"
    ".msg{margin-top:12px;font-size:14px;white-space:pre-wrap}"
    ".ok{color:var(--ok)}.err{color:var(--err)}.warn{color:var(--warn)}"
    ".toast{position:fixed;left:50%;top:14px;transform:translateX(-50%);background:#111927;color:#fff;padding:.7rem 1rem;border-radius:10px;box-shadow:0 10px 28px rgba(0,0,0,.35);z-index:9999;opacity:0;pointer-events:none;transition:opacity .2s}"
    ".toast.show{opacity:1}"
    ".hr{height:1px;background:linear-gradient(90deg,transparent,var(--line2),transparent);margin:16px 0}"
    ".two-col{display:grid;grid-template-columns:1fr 1fr;gap:clamp(10px,2.2vw,18px)}"
    "@media(max-width:720px){.two-col{grid-template-columns:1fr}.btn{width:100%;justify-content:center}.row.wrap-to-col{flex-direction:column;align-items:stretch}}"
    ".hint{font-size:12px;color:var(--muted)}"
    ".connecting{padding:26px 14px;text-align:center}"
    ".spinner{width:48px;height:48px;border-radius:50%;border:4px solid var(--line);border-top-color:var(--pri);margin:10px auto 14px;animation:sp 1s linear infinite}"
    "@keyframes sp{to{transform:rotate(360deg)}}"
    ".success-icon{width:48px;height:48px;border-radius:50%;background:var(--ok);color:#fff;display:flex;align-items:center;justify-content:center;font-size:24px;margin:10px auto 14px;animation:successPulse 1s ease-out}"
    "@keyframes successPulse{0%{transform:scale(0);opacity:0}50%{transform:scale(1.1)}100%{transform:scale(1);opacity:1}}"
    ".steps{margin:10px auto 0;text-align:left;max-width:560px;color:#5a6472;line-height:1.7}"
    ".steps li{margin:.25rem 0;opacity:0;transform:translateY(10px);animation:fadeInUp .6s ease forwards}"
    ".steps li:nth-child(1){animation-delay:.2s}"
    ".steps li:nth-child(2){animation-delay:.4s}"
    ".steps li:nth-child(3){animation-delay:.6s}"
    ".steps li:nth-child(4){animation-delay:.8s}"
    ".steps li:nth-child(5){animation-delay:1s}"
    "@keyframes fadeInUp{to{opacity:1;transform:translateY(0)}}"
    ".badge{display:inline-flex;align-items:center;gap:6px;padding:.28rem .56rem;border-radius:999px;background:rgba(11,107,255,.12);color:var(--pri);font-weight:800;font-size:12px;letter-spacing:.3px}"
    ".big{font-size:15px}"
    ".countdown{display:inline-flex;align-items:center;gap:8px;margin:12px 0;padding:8px 16px;background:rgba(11,107,255,.08);border-radius:20px;font-weight:600;color:var(--pri)}"
    ".countdown-num{font-size:18px;font-weight:800;min-width:24px;text-align:center}"
    ".progress-bar{width:100%;height:4px;background:var(--line2);border-radius:2px;overflow:hidden;margin:16px 0}"
    ".progress-fill{height:100%;background:linear-gradient(90deg,var(--pri),#4c8dff);border-radius:2px;width:0%;transition:width .3s ease}"
    ".status-dot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:8px;background:var(--muted)}"
    ".status-dot.active{background:var(--ok);animation:pulse 1.5s ease-in-out infinite}"
    "@keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.7;transform:scale(1.1)}}"
    ".result-section{display:none;margin-top:20px;padding:20px;background:rgba(18,124,62,.08);border-radius:12px;border:1px solid rgba(18,124,62,.2)}"
    ".result-section.show{display:block;animation:fadeInUp .6s ease}"
    ".reset-info{margin-top:16px;padding:16px;background:rgba(155,108,0,.08);border-radius:8px;border:1px solid rgba(155,108,0,.2)}"
    ".reset-info h4{margin:0 0 8px;color:var(--warn);font-size:14px;font-weight:600}"
    ".reset-info p{margin:4px 0;font-size:13px;color:var(--muted);line-height:1.5}"
    ".i{font-style:normal;opacity:.9}"
    "</style>"
    "</head><body><div class='wrap'>"
    "<div class='card'>"
    "  <div class='hd'><h1 class='title'>📶 WiFi 配网</h1></div>"
    "  <div class='bd'>"
    "    <div id='page-form'>"
    "      <div class='row' style='justify-content:space-between'>"
    "        <div class='badge'>✨ 配网向导</div>"
    "        <span id='scanHint' class='hint'>请输入WiFi信息或使用扫描功能</span>"
    "      </div>"
    "      <div class='hr'></div>"
    "      <form onsubmit='ev(event)'>"
    "        <div class='two-col'>"
    "          <div>"
    "            <label>📶 SSID</label>"
    "            <input id='ssid' required maxlength='63' placeholder='请输入WiFi名称'/>"
    "          </div>"
    "          <div>"
    "            <label>🔒 密码</label>"
    "            <input id='pwd' type='password' maxlength='63' placeholder='请输入WiFi密码'/>"
    "          </div>"
    "        </div>"
    "        <div class='row' style='margin-top:12px;justify-content:space-between'>"
    "          <label class='muted' style='display:flex;align-items:center;gap:8px;margin:0'><input id='save' type='checkbox' checked /> 保存到设备</label>"
    "          <div class='row' style='gap:10px'>"
    "            <button class='btn' type='submit' id='connBtn'>🟢 连接</button>"
    "          </div>"
    "        </div>"
    "      </form>"
    "      <div id='msg' class='msg muted'></div>"
    "      <div class='hr'></div>"
    "      <div class='row wrap-to-col' style='gap:12px'>"
    "        <button class='btn sec' id='scanBtn'>🔍 扫描附近WiFi</button>"
    "      </div>"
    "      <div id='scanList' class='list' style='display:none;margin-top:10px'></div>"
    "    </div>"
    "    <div id='page-connecting' style='display:none'>"
    "      <div class='connecting'>"
    "        <div class='spinner' id='spinner'></div>"
    "        <div class='success-icon' id='successIcon' style='display:none'>✅</div>"
    "        <div class='big' style='font-weight:700' id='statusTitle'>⏳ 正在连接路由器…</div>"
    "        <div id='connSsid' class='muted' style='margin-top:6px'></div>"
    "        <div class='countdown' id='countdown'>"
    "          <span>⏰ 预计剩余时间：</span>"
    "          <span class='countdown-num' id='countdownNum'>15</span>"
    "          <span>秒</span>"
    "        </div>"
    "        <div class='progress-bar'>"
    "          <div class='progress-fill' id='progressFill'></div>"
    "        </div>"
    "        <div class='hr'></div>"
    "        <ul class='steps' id='stepsList'>"
    "          <li><span class='status-dot active'></span>✅ 设备已收到配网信息，正在切换至 STA 模式</li>"
    "          <li><span class='status-dot'></span>🔄 开始连接路由器，验证WiFi密码</li>"
    "          <li><span class='status-dot'></span>📡 获取IP地址，建立网络连接</li>"
    "          <li><span class='status-dot'></span>🌐 连接成功，设备即将切换网络</li>"
    "          <li><span class='status-dot'></span>📱 手机将断开设备热点，请重新连接WiFi</li>"
    "        </ul>"
    "        <div class='hr'></div>"
    "        <div class='hint'>💡 提示：连接过程中请保持设备与路由器距离适中，避免信号干扰</div>"
    "        <div class='result-section' id='resultSection'>"
    "          <div style='text-align:center;margin-bottom:16px'>"
    "            <div style='font-size:18px;font-weight:700;color:var(--ok);margin-bottom:8px'>🎉 配网完成！</div>"
    "            <div style='color:var(--muted);font-size:14px'>设备已成功连接到WiFi网络</div>"
    "          </div>"
    "          <div style='background:rgba(18,124,62,.1);padding:12px;border-radius:8px;margin-bottom:16px'>"
    "            <div style='font-weight:600;color:var(--ok);margin-bottom:4px'>📋 下一步操作：</div>"
    "            <div style='font-size:13px;color:var(--muted);line-height:1.6'>"
    "              1. 返回手机WiFi设置，重新连接到您的路由器<br/>"
    "              2. 检查设备指示灯是否显示联网状态<br/>"
    "              3. 如设备未联网，请重新进入配网模式"
    "            </div>"
    "          </div>"
    "          <div class='reset-info'>"
    "            <h4>🔧 重置方法</h4>"
    "            <p><strong>重新配网：</strong>同时长按设备【音量+】和【音量-】按键 5 秒，设备将重新进入配网模式</p>"
    "            <p><strong>恢复出厂：</strong>长按设备【模式】按键 10 秒，清除所有配置并恢复出厂设置</p>"
    "          </div>"
    "        </div>"
    "      </div>"
    "    </div>"
    "  </div>"
    "</div>"
    "<div id='toast' class='toast' role='status' aria-live='polite'></div>"
    "</div>"
    "<script>"
    "const $=s=>document.querySelector(s);"
    "const scanBtn=$('#scanBtn'), scanList=$('#scanList'), scanHint=$('#scanHint'), msg=$('#msg');"
    "const pageForm=$('#page-form'), pageConn=$('#page-connecting'), connSsid=$('#connSsid');"
    "const countdownNum=$('#countdownNum'), progressFill=$('#progressFill'), stepsList=$('#stepsList');"
    "const spinner=$('#spinner'), successIcon=$('#successIcon'), statusTitle=$('#statusTitle');"
    "const countdown=$('#countdown'), resultSection=$('#resultSection');"
    "let countdownTimer = null, stepTimer = null;"
    "function note(t,cls=''){msg.className='msg '+(cls||''); msg.textContent=t}"
    "function tip(t,dur=3200){const el=$('#toast'); el.textContent=t; el.classList.add('show'); setTimeout(()=>el.classList.remove('show'),dur)}"
    "function fill(ssid){$('#ssid').value=ssid; note('已选择: '+ssid,'ok')}"
    "function rssiBar(r){return (r||0)+' dBm'}"
    "function esc(s){return String(s||'').replace(/[&<>\\\"']/g,c=>({ '&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;' }[c]))}"
    "function startCountdown() {"
    "  let time = 15;"
    "  const totalTime = 15;"
    "  countdownTimer = setInterval(() => {"
    "    time--;"
    "    countdownNum.textContent = time;"
    "    const progress = ((totalTime - time) / totalTime) * 100;"
    "    progressFill.style.width = progress + '%';"
    "    if (time <= 0) {"
    "      clearInterval(countdownTimer);"
    "      countdownNum.textContent = '0';"
    "      progressFill.style.width = '100%';"
    "      spinner.style.display = 'none';"
    "      successIcon.style.display = 'flex';"
    "      statusTitle.textContent = '🎉 配网完成！';"
    "      statusTitle.style.color = 'var(--ok)';"
    "      countdown.style.display = 'none';"
    "      resultSection.classList.add('show');"
    "      tip('配网完成！请检查设备联网状态', 5000);"
    "    }"
    "  }, 1000);"
    "}"
    "function startStepAnimation() {"
    "  const steps = stepsList.querySelectorAll('li');"
    "  let currentStep = 0;"
    "  stepTimer = setInterval(() => {"
    "    if (currentStep < steps.length) {"
    "      const dot = steps[currentStep].querySelector('.status-dot');"
    "      if (dot) dot.classList.add('active');"
    "      currentStep++;"
    "    } else {"
    "      clearInterval(stepTimer);"
    "    }"
    "  }, 3000);"
    "}"
    "function stopAllTimers() {"
    "  if (countdownTimer) clearInterval(countdownTimer);"
    "  if (stepTimer) clearInterval(stepTimer);"
    "}"
    "async function scan(){"
    " try{scanBtn.disabled=true; scanHint.textContent='扫描中…';"
    "  const r=await fetch('/scan',{cache:'no-store'}); const arr=await r.json();"
    "  if(Array.isArray(arr)&&arr.length){"
    "    scanList.style.display='block';"
    "    scanList.innerHTML=arr.map(o=>`<div class=\\\"item\\\" data-ssid=\\\"${esc(o.ssid)}\\\"><span class=\\\"ssid\\\">${esc(o.ssid)||'(隐藏)'}<\\/span><span class='rssi'>📶 ${rssiBar(o.rssi)}<\\/span><\\/div>`).join('');"
    "  }else{scanList.style.display='none'; note('未扫描到可用热点','warn')}"
    " }catch(e){note('扫描失败: '+e,'err')}finally{scanBtn.disabled=false; scanHint.textContent='可再次扫描，或手动输入'}"
    "}"
    "function showConnecting(name){"
    " pageForm.style.display='none';"
    " pageConn.style.display='block';"
    " connSsid.textContent='目标路由器：'+(name||'-');"
    " stopAllTimers();"
    " startCountdown();"
    " startStepAnimation();"
    "}"
    "async function ev(e){e.preventDefault();"
    " const s=$('#ssid').value.trim(), p=$('#pwd').value, save=$('#save').checked?1:0;"
    " if(!s){note('SSID 不能为空','err'); return}"
    " $('#connBtn').disabled=true; note('正在提交…');"
    " try{const u='/wifi_cfg?ssid='+encodeURIComponent(s)+'&pwd='+encodeURIComponent(p)+'&save='+save;"
    "  const r=await fetch(u,{cache:'no-store'}); const j=await r.json();"
    "  if(j.ok){"
    "    tip('已提交，设备即将切换网络');"
    "    showConnecting(s);"
    "  }else{"
    "    note('提交失败: '+(j.msg||''),'err');"
    "  }"
    " }catch(e){note('请求失败: '+e,'err')}finally{$('#connBtn').disabled=false}"
    "}"
    "scanBtn.onclick=scan;"
    "setTimeout(scan,800);"
    "scanList.addEventListener('click',e=>{const it=e.target.closest('.item'); if(it&&it.dataset.ssid!=null){ fill(it.dataset.ssid); }});"
    "</script>"
    "</body></html>";